-- Diagnosis
-- Create by zouyb
-- 网络诊断

-- 到腾讯DNS获取ip
function getIpFromWebDns(hostname, callback)
    local url = 'http://119.29.29.29/d?dn='..hostname;
    local function whenResponse(responseData)
        if not responseData then
            callback(false);
        end

        local arr = string.explode(responseData, ";");
        if #arr > 0 then
            callback(true, arr[1]);
        else
            callback(false);
        end
    end
    getRemoteHostData(url, whenResponse, false);
end

-- 一般的DNS解析
function getIpFromLocalDns(hostname)
    local socket = require("socket");
    return socket.dns.toip(hostname);
end

-- 从URL中解析出域名
function getHostnameFromUrl(url)
    local _, __, hostname = string.find(url, "http[s]*://(.-)/.*");
    return hostname;
end

-- 获取诊断ID
function getDiagnoseID()
    local diagId = UserDefaultM.getStringForKey("diag_id");
    if diagId == nil or diagId == "" then
        -- 生成诊断ID
        local socket = require "socket";
        math.randomseed(socket.gettime()*10000);

        local numbers = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
        local id = "";
        for i = 1, 6 do
            id = id .. numbers[math.random(1, 10)];
        end

        diagId = id;
        UserDefaultM.setStringForKey("diag_id", id);
    end
    return diagId;
end


-- 判断是否ip
function isIp(str)
    _, _, p1, p2, p3, p4 = string.find(string.trim(str), "^(%d+)%.(%d+)%.(%d+)%.(%d+)$");
    if p1 and p2 and p3 and p4 then
        return true;
    end

    return false;
end

-- 诊断式下载
function diagnoseDownload(url)
    DIAGNOSE_RESULT = DIAGNOSE_RESULT or {};
    DIAGNOSE_RESULT[url] = DIAGNOSE_RESULT[url] or {};

    local hostname = getHostnameFromUrl(url);
    hostname = string.trim(string.explode(hostname, ":")[1]);
    if not isIp(hostname) then
        local function callback(ret, ip)
            if ret then
                local newUrl = string.gsub(url, hostname, ip);
                local function whenResponse(responseData)
                    if not responseData then
                        DIAGNOSE_RESULT[url]["fix_url"] = newUrl;
                        DIAGNOSE_RESULT[url]["result"] = "false";
                        return;
                    end

                    -- 记录可用的ip, 方便后续重登陆使用
                    FIX_HOSTNAME_LIST = FIX_HOSTNAME_LIST or {};
                    FIX_HOSTNAME_LIST[hostname] = ip;

                    DIAGNOSE_RESULT[url]["fix_url"] = newUrl;
                    DIAGNOSE_RESULT[url]["result"] = "true";
                end
                print("newUrl:"..newUrl);
                getRemoteHostData(newUrl, whenResponse, false);
            end
        end
        getIpFromWebDns(hostname, callback);
    else
        DIAGNOSE_RESULT[url]["fix_url"] = url;
        DIAGNOSE_RESULT[url]["result"] = "true";
    end
end

-- 修复URL
function fixUrl(url)
    local hostname = getHostnameFromUrl(url);
    hostname = string.trim(string.explode(hostname, ":")[1]);
    if FIX_HOSTNAME_LIST and FIX_HOSTNAME_LIST[hostname] then
        -- 有网络修复过的记录，直接将hostname转成ip
        url = string.gsub(url, hostname, FIX_HOSTNAME_LIST[hostname]);
    end

    return url;
end

-- 修复HostName
function fixHostname(hostname)
    if FIX_HOSTNAME_LIST and FIX_HOSTNAME_LIST[hostname] then
        return FIX_HOSTNAME_LIST[hostname];
    end

    return hostname;
end

function diagTest()
    DIAGNOSE_RESULT = nil;

    local url;

    -- dislist下载地址
    url = 'http://rs.qcplay.com/slimego/googleplay/dislist/res_161105/dislist.json';
    diagnoseDownload(url);

    url = 'https://s3.amazonaws.com/qcplay.resouce/slimego/googleplay/dislist/res_161105/dislist.json';
    diagnoseDownload(url);

    -- 资源下载地址
    url = 'http://rs.qcplay.com/slimego/google_tw/latest/google_tw_1.1.5/version.manifest';
    diagnoseDownload(url);
end

-- 开始诊断
function startDiagnose(callback)
    local id = getDiagnoseID();
    local url = DIAGNOSE_URL .. "?cmd=get_info&id=" .. id;

    local hostname = getHostnameFromUrl(url);
    hostname = string.trim(string.explode(hostname, ":")[1]);

    local function nextStep(ret, ip)
        if ret then
            local newUrl = string.gsub(url, hostname, ip);
            -- 从诊断后台获取诊断指令
            local function whenResponse(responseData)
                if not responseData then
                    callback(false);
                end

                runDiagnoseCmds(responseData, callback);
            end
            getRemoteHostData(newUrl, whenResponse, false);
        end
    end

    if not isIp(hostname) then
        getIpFromWebDns(hostname, nextStep);
    else
        nextStep(true, hostname);
    end
end

-- 执行指令
function runDiagnoseCmds(data, callback)
    local node = AUTOPATCH_UI or UIMgr.getCurrentScene();

    -- 执行诊断指令
    catch(loadstring(data));

    local function sendResult()
        if onDiagReportSend then
            onDiagReportSend();
        end

        -- 结果会放在DIAGNOSE_RESULT里面，做一下base64编码
        require("game/base/encrypt/MyBase64");
        local result = MyBase64.encode(json.encode(DIAGNOSE_RESULT));

        -- 发送给后台
        local id = getDiagnoseID();
        local url = DIAGNOSE_URL .. "?cmd=send_result&id=" .. id .. "&result=" ..result;
        getRemoteHostData(url, nil, false);
    end

    local function check()
        for _, info in pairs(DIAGNOSE_RESULT) do
            if info["result"] == nil then
                -- 需要等到所有结果都出来在发送报告
                performWithDelay(node, check, 1);
                return;
            end
        end

        -- 发送报告
        sendResult();

        callback(true);
    end

    performWithDelay(node, check, 1);
end
